package com.duubee.btframe.utils;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.duubee.btframe.interfaces.BtIgnore;
import com.duubee.btframe.interfaces.BtLogicDeleted;
import com.duubee.btframe.interfaces.BtTableId;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * Fs框架处理工具类
 */
public class BtFrameUtil {

    public static final String BEGIN = "_begin";
    public static final String END = "_end";
    public static final String LEFT_LIKE = "_LEFT_LIKE";
    public static final String RIGHT_LIKE = "_RIGHT_LIKE";
    public static final String LIKE = "_LIKE";
    public static final String NOTLIKE = "_NOTLIKE";
    public static final String GT = "_GT";
    public static final String LT = "_LT";
    public static final String EQ = "_eq";
    public static final String NE = "_ne";
    public static final String GT_EQ = "_gt_eq";
    public static final String LT_EQ = "_lt_eq";
    public static final String ISNULL = "_isNull";
    public static final String ISNOTNULL = "_isNotNull";
    public static final String IN = "_IN";
    public static final String NOTIN = "_NOTIN";
    public static final String OR = "FsQueryOr_";
    public static final String TODAY = "_TODAY";
    public static final String LEFT_JOIN = "LEFT_JOIN_";
    public static final String RIGHT_JOIN = "RIGHT_JOIN_";
    public static final String INNER_JOIN = "INNER_JOIN_";
    public static final String GROUP_BY = "GROUP_BY";

    public static final String STAR = "*";
    public static final String COMMA = ",";

    /**
     * 排序列
     */
    public static final String ORDER_COLUMN = "column";
    /**
     * 排序方式
     */
    public static final String ORDER_TYPE = "order";
    /**
     * 查询字段
     */
    public static final String FIELDS_COLUMN = "fields";
    public static final String FIELD_COLUMN = "field";


    /**
     * 获取sql列名
     *
     * @param field 字段
     * @return sql列名
     */
    public static String getSQLColumnName(Field field) {
        if (field == null) {
            return null;
        }
        String str = null;
        TableField tableField = null;
        if (!(field.isAnnotationPresent(TableField.class) &&
                ((tableField = field.getAnnotation(TableField.class))) != null &&
                !((str = tableField.value()).isEmpty()))) {
            //驼峰命名转SQL命名
            str = toSQLName(field.getName());
        }
        return str.replace("`", "");
    }

    /**
     * 驼峰命名转数据库命名
     *
     * @param column 驼峰命名列名
     * @return 数据库命名
     */
    public static String toSQLName(String column) {
        if (column == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        char[] arr = column.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            char c = arr[i];
            if (c >= 'A' && c <= 'Z') {
                if (i != 0) {
                    sb.append("_");
                }
                sb.append(String.valueOf(c).toLowerCase());

            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 数据库命名转驼峰命名
     *
     * @param column 列
     * @return 驼峰命名
     */
    public static String toEntityName(String column) {
        if (column == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        String[] str = column.split("_");
        for (String temp : str) {
            if (sb.length() == 0) {
                if (!BtStringUtil.isEmpty(temp)) {
                    sb.append(temp.toLowerCase());
                }
            } else {
                sb.append(BtStringUtil.getConvert(temp));
            }
        }
        return sb.toString();
    }

    /**
     * 是否拥有指定修饰符
     *
     * @param modifier  访问修饰权限值
     * @param modifiers 验证是否拥有的修饰符集合
     * @return flag
     */
    public static boolean hashModifier(int modifier, String... modifiers) {
        boolean flag = false;
        int searchMods = 0x0;
        for (int i = 1; i < modifiers.length; i++) {
            searchMods |= modifierFromString(modifiers[i]);
        }
        if ((modifier & searchMods) == searchMods) {
            flag = true;
        }

        return flag;
    }

    /**
     * 获取表名
     *
     * @param t 实体类型
     * @return 表名
     */
    public static <T> String getTableName(Class<T> t) {
        //获取表名
        TableName table = t.getAnnotation(TableName.class);
        if (table != null) {
            return table.value();
        } else {
            return BtFrameUtil.toSQLName(t.getSimpleName());
        }
    }

    /**
     * 获取修饰符值
     *
     * @param s 修饰符
     * @return 修饰符值
     */
    private static int modifierFromString(String s) {
        int m = 0x0;
        if ("public".equals(s))
            m |= Modifier.PUBLIC;
        else if ("protected".equals(s))
            m |= Modifier.PROTECTED;
        else if ("private".equals(s))
            m |= Modifier.PRIVATE;
        else if ("static".equals(s))
            m |= Modifier.STATIC;
        else if ("final".equals(s))
            m |= Modifier.FINAL;
        else if ("transient".equals(s))
            m |= Modifier.TRANSIENT;
        else if ("volatile".equals(s))
            m |= Modifier.VOLATILE;
        return m;
    }

    /**
     * 取出主键列
     *
     * @param fields 字段集合
     * @return 主键列
     */
    public static Field getTableId(Field[] fields) {
        Field back = null;

        for (Field f : fields) {
            if (f.isAnnotationPresent(BtTableId.class) && !f.isAnnotationPresent(BtIgnore.class)) {
                back = f;
                break;
            }
        }
        if (back == null) {
            for (Field f : fields) {
                if (f.isAnnotationPresent(TableId.class) && !f.isAnnotationPresent(BtIgnore.class)) {
                    back = f;
                    break;
                }
            }

            //如果没有TableId注解，则默认找名字为(id)的字段
            if (back == null) {
                for (Field f : fields) {
                    if (f.getName().equals("id") && !f.isAnnotationPresent(BtIgnore.class)) {
                        back = f;
                        break;
                    }
                }
            }
        }


        return back;
    }

    /**
     * 取出逻辑删除字段
     *
     * @param fields 字段集合
     * @return 主键列
     */
    public static Field getLogicDeletedField(Field[] fields) {
        for (Field f : fields) {
            if (f.isAnnotationPresent(BtLogicDeleted.class)) {
                return f;
            }
        }
        return null;
    }

    /**
     * 判断是否为序列号id
     *
     * @param field 字段
     * @return 是否为序号id
     */
    public static boolean checkIsModifier(Field field) {
        return BtFrameUtil.hashModifier(field.getModifiers(), "private", "static", "final");
    }
}
